package com.cfweb.controller.system;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.cfweb.api.SpaceApi;
import com.cfweb.api.UserApi;
import com.cfweb.controller.LoginHandler;
import com.cfweb.dao.AppTemplateMapper;
import com.cfweb.dao.AuthUserMapper;
import com.cfweb.dao.CfAppMapper;
import com.cfweb.dao.CfServiceInstanceMapper;
import com.cfweb.dao.CfUserMapper;
import com.cfweb.domain.AppTemplate;
import com.cfweb.domain.AppTemplateExample;
import com.cfweb.domain.AuthUser;
import com.cfweb.domain.AuthUserExample;
import com.cfweb.domain.CfApp;
import com.cfweb.domain.CfAppExample;
import com.cfweb.domain.CfServiceInstance;
import com.cfweb.domain.CfServiceInstanceExample;
import com.cfweb.domain.CfUser;
import com.cfweb.domain.CfUserExample;
import com.cfweb.util.ExtJSResponse;

/**
 * 
 * @author dt
 *
 */
@Service
@Path("/space")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class SpaceManagement {
	
	Logger logger = Logger.getLogger(SpaceManagement.class);
	
	@Autowired  
	private HttpSession session; 
	@Autowired
	private CfUserMapper cuMapper;
	@Autowired
	private AuthUserMapper auMapper;
	
	@Autowired
	private AppTemplateMapper apptemMapper;
	@Autowired
	private CfAppMapper cfappMapper;
	
	@Autowired
	private CfServiceInstanceMapper cfserinsMapper;
	
	
	/**
     * list all of spaces in the org
     * @param 无
     * @return list
     */
	@Path("/listall")
	@GET
	public ExtJSResponse listall() {
		List<Map<String, Object>> spaces = new ArrayList<Map<String, Object>>();
		try {
			spaces = SpaceApi.list_spaces(session);
		} catch(Exception e) {
			logger.error(e);
			return ExtJSResponse.errorRes();
		}
		return ExtJSResponse.successResWithData(spaces);
	}
	
	/**
     * list all of spaces in the org
     * @param orgName
     * @return list
     */
	@Path("/list")
	@GET
	public ExtJSResponse list(@QueryParam("orgName") String orgName) throws Exception {
		List<Map<String, Object>> spaces = new ArrayList<Map<String, Object>>();
		//System.out.println(orgName);
		try {
			spaces = SpaceApi.list_spaces_by_org(session, orgName);
		} catch(Exception e) {
			throw e;
		}
		return ExtJSResponse.successResWithData(spaces);
	}
	
	/**
     * change space in the org
     * @param orgName
     * @param spaceName
     * @return success or error
     */
	/*
	@Path("/change")
	@GET
	public ExtJSResponse change(@QueryParam("orgName") String orgName, @QueryParam("spaceName") String spaceName) {
		try {
			String username = (String) session.getAttribute(LoginHandler.USERNAME);
			String password = (String) session.getAttribute(LoginHandler.PASSWORD);
			URL target = (URL) session.getAttribute(LoginHandler.TARGET);
			CloudCredentials credentials = new CloudCredentials(username, password);
			CloudFoundryClient client = new CloudFoundryClient(credentials,
					target, orgName, spaceName);
			CfUserExample cuEx = new CfUserExample();
			cuEx.createCriteria().andUserNameEqualTo(username);
//								.andUserPassEqualTo(password);
			CfUser user = cuMapper.selectByExample(cuEx).get(0);
			user.setLastOrg(orgName);
			user.setLastSpace(spaceName);
			cuMapper.updateByPrimaryKey(user);
			session.setAttribute(LoginHandler.CLIENT, client);
			OAuth2AccessToken token = client.login();
			session.setAttribute(LoginHandler.TOKEN, "bearer " + token.getValue());
		} catch(Exception e) {
			logger.error(e);
			return ExtJSResponse.errorRes();
		}
		return ExtJSResponse.successRes();
	}*/
	
	/**
     * add a space in the org
     * @param orgName
     * @param spaceName
     * @return success or error
     */
	@Path("/add")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse add(@FormParam("orgName") String orgName, 
			@FormParam("spaceName") String spaceName) throws Exception {
		if (SpaceApi.create_space(session, orgName, spaceName)) {
			AuthUser au = new AuthUser();
			au.setAuthType("SpaceManager");
			au.setOrgName(orgName);
			au.setSpaceName(spaceName);
			CfUserExample cuEx = new CfUserExample();
			cuEx.createCriteria().andUserNameEqualTo((String) session.getAttribute(LoginHandler.USERNAME));
			int userId = cuMapper.selectByExample(cuEx).get(0).getId();
			au.setUserId(userId);
			auMapper.insert(au);
			au.setAuthType("SpaceDeveloper");
			auMapper.insert(au);
			return ExtJSResponse.successRes();
		}
		return ExtJSResponse.errorRes();
	}
	
	/**
     * delete a space in the org
     * @param orgName
     * @param spaceName
     * @return success or error
     */
	@Path("/delete")
	@GET
	public ExtJSResponse delete(@QueryParam("orgName") String orgName,
			@QueryParam("spaceName") String spaceName) throws Exception {
		if (SpaceApi.delete_space(session, orgName, spaceName)) {
			AuthUserExample auEx = new AuthUserExample();
			auEx.createCriteria().andOrgNameEqualTo(orgName).andSpaceNameEqualTo(spaceName);
			auMapper.deleteByExample(auEx);
			CfUserExample cuEx = new CfUserExample();
			cuEx.createCriteria().andLastOrgEqualTo(orgName).andLastSpaceEqualTo(spaceName);
			List<CfUser> culist = cuMapper.selectByExample(cuEx);
			AppTemplateExample apptemEx = new AppTemplateExample();
			apptemEx.createCriteria().andOrgEqualTo(orgName).andSpaceEqualTo(spaceName);
			apptemMapper.deleteByExample(apptemEx);
			CfAppExample cfappEx = new CfAppExample();
			cfappEx.createCriteria().andOrgEqualTo(orgName).andSpaceEqualTo(spaceName);
			cfappMapper.deleteByExample(cfappEx);
			CfServiceInstanceExample cfserInsEx = new CfServiceInstanceExample();
			cfserInsEx.createCriteria().andOrgEqualTo(orgName).andSpaceEqualTo(spaceName);
			cfserinsMapper.deleteByExample(cfserInsEx);
			if(culist.size() != 0) {
				for(CfUser cu:culist) {
					cu.setLastSpace(null);
					cuMapper.updateByPrimaryKey(cu);
				}
			}
			if(spaceName.equals(session.getAttribute(LoginHandler.SPACE))) {
				session.setAttribute(LoginHandler.SPACE, null);
			}
			List<String> lau = new ArrayList<String>();
			lau.add((String) session.getAttribute(LoginHandler.ORG));
			lau.add((String) session.getAttribute(LoginHandler.SPACE));
			return ExtJSResponse.successResWithData(lau);
		}
		return ExtJSResponse.errorRes();
	}
	
	/**
     * rename a space in the org
     * @param orgName
     * @param spaceName
     * @param newName
     * @return success or error
     */
	@Path("/rename")
	@POST
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public ExtJSResponse rename(@FormParam("orgName") String orgName, 
			@FormParam("spaceName") String spaceName,
			@FormParam("newName") String newName) throws Exception {	
		AuthUserExample auEx = new AuthUserExample();
		auEx.createCriteria().andSpaceNameEqualTo(spaceName).andOrgNameEqualTo(orgName);
		CfUserExample cuEx = new CfUserExample();
		cuEx.createCriteria().andLastOrgEqualTo(orgName).andLastSpaceEqualTo(spaceName);
		AppTemplateExample apptemEx = new AppTemplateExample();
		apptemEx.createCriteria().andOrgEqualTo(orgName).andSpaceEqualTo(spaceName);
		CfAppExample cfappEx = new CfAppExample();
		cfappEx.createCriteria().andOrgEqualTo(orgName).andSpaceEqualTo(spaceName);
		CfServiceInstanceExample cfserIns = new CfServiceInstanceExample();
		cfserIns.createCriteria().andOrgEqualTo(orgName).andSpaceEqualTo(spaceName);
		if (SpaceApi.rename_space(session, orgName, spaceName, newName)) {
			List<AuthUser> aulist = auMapper.selectByExample(auEx);
			if(aulist.size() != 0) {
				for(AuthUser au:aulist) {
					au.setSpaceName(newName);
					auMapper.updateByPrimaryKey(au);
				}	
			}
			List<CfUser> culist = cuMapper.selectByExample(cuEx);
			if(culist.size() != 0) {
				for(CfUser cu:culist) {
					cu.setLastSpace(newName);
					cuMapper.updateByPrimaryKey(cu);
				}
			}
			List<AppTemplate> atemlist = apptemMapper.selectByExample(apptemEx);
			if(atemlist.size() != 0) {
				for(AppTemplate atem:atemlist) {
					atem.setSpace(newName);
					apptemMapper.updateByPrimaryKey(atem);
				}
			}
			List<CfApp> cfalist = cfappMapper.selectByExample(cfappEx);
			if(cfalist.size() != 0) {
				for(CfApp cfa:cfalist) {
					cfa.setSpace(newName);
					cfappMapper.updateByPrimaryKey(cfa);
				}
			}
			List<CfServiceInstance> cfserlist = cfserinsMapper.selectByExample(cfserIns);
			if(cfserlist.size() != 0) {
				for(CfServiceInstance cfser:cfserlist) {
					cfser.setSpace(newName);
					cfserinsMapper.updateByPrimaryKey(cfser);
				}
			}
			return ExtJSResponse.successRes();
		}
		
		if(spaceName.equals(session.getAttribute(LoginHandler.SPACE))) {
			session.setAttribute(LoginHandler.SPACE, newName);
		}
		return ExtJSResponse.errorRes();
	}
	
	/**
     * check a space for the same name in the org
     * @param orgName
     * @param spaceName
     * @return success or error
     */
	@Path("/checkSpaceName")
	@GET
	public ExtJSResponse checkSpaceName(@QueryParam("orgName") String orgName, @QueryParam("spaceName") String spaceName) throws Exception {
		try {
			if(!UserApi.get_space_id(session, orgName, spaceName).isEmpty()) {
				return ExtJSResponse.successResWithData(false);
			}
		} catch(Exception e) {
			throw e;
		}
		return ExtJSResponse.successResWithData(true);
	}
}
